﻿using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Enumeradores;
using Onshi.POS.Repositorios;
using Onshi.POS.Articulos.Vistas;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Onshi.POS.Articulos
{
    public class ArticulosPresentador
    {
        #region Constructores

        public ArticulosPresentador(IArticulos vista)
        {
            this.vista = vista;
        }

        #endregion

        #region Atributos

        private IArticulos vista;
        private List<Articulo> listado;

        #endregion

        #region Propiedades

        private RepositorioEventos RepositorioEventos
        {
            get { return new RepositorioEventos(); }
        }

        private RepositorioUsuarios RepositorioUsuarios
        {
            get { return new RepositorioUsuarios(); }
        }

        private RepositorioRegistros RepositorioRegistros
        {
            get { return new RepositorioRegistros(); }
        }

        private RepositorioPermisos RepositorioPermisos
        {
            get { return new RepositorioPermisos(); }
        }

        private RepositorioArticulos RepositorioArticulos
        {
            get { return new RepositorioArticulos(); }
        }

        #endregion

        #region Metodos

        private void CargarFiltrarLista()
        {
            listado = RepositorioArticulos.DevolverTodos();
            Filtrar();
        }

        public void Inicializar()
        {
            listado = RepositorioArticulos.DevolverTodos();
            vista.ListadoArticulos = listado.Where(x => !x.EstaEliminado).ToList();
        }

        public void Nuevo()
        {
            CargarFiltrarLista();
        }

        public void Modificar()
        {
            CargarFiltrarLista();
        }

        public void Eliminar()
        {
            var usuario = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.ArticulosBaja))
                throw new Exception("Permisos insuficientes");

            var articulo = RepositorioArticulos.DevolverPorId(vista.IdArticulo, true);
            if (articulo == null)
                throw new Exception("El articulo no existe");
            if (articulo.EstaEliminado)
                throw new Exception("El articulo ya se encuentra eliminado");
            articulo.EstaEliminado = true;

            var registro = new Registro();
            registro.Usuario = usuario;
            registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.ArticulosBaja);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            RepositorioArticulos.Modificar(articulo);
            RepositorioRegistros.Insertar(registro, articulo);

            CargarFiltrarLista();
        }

        public void Habilitar()
        {
            var usuario = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.ArticulosHabilitacion))
                throw new Exception("Permisos insuficientes");

            var articulo = RepositorioArticulos.DevolverPorId(vista.IdArticulo, true);
            if (articulo == null)
                throw new Exception("El articulo no existe");
            if (!articulo.EstaEliminado)
                throw new Exception("El articulo ya se encuentra habilitado");
            articulo.EstaEliminado = false;

            var registro = new Registro();
            registro.Usuario = usuario;
            registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.ArticulosHabilitacion);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            RepositorioArticulos.Modificar(articulo);
            RepositorioRegistros.Insertar(registro, articulo);

            CargarFiltrarLista();
        }

        public void Actualizar()
        {
            CargarFiltrarLista();
        }

        public void Filtrar()
        {
            var consulta = (from item in listado
                            where item.Codigo.Trim().ToLower().Contains(vista.CodigoFiltro.Trim().ToLower())
                            & item.Nombre.Trim().ToLower().Contains(vista.NombreFiltro.Trim().ToLower())
                            & item.Marca.Id == (vista.IdMarcaFiltro == (Int32)EnumMarcas.Todos ? item.Marca.Id : vista.IdMarcaFiltro)
                            & item.DescuentoRecargoCantidad.Id == (vista.IdDescuentoRecargoFiltro == (Int32)EnumDescuentosRecargosCantidades.Todos ? item.DescuentoRecargoCantidad.Id : vista.IdDescuentoRecargoFiltro)
                            & item.DescuentoRecargoFechaHora.Id == (vista.IdPromocionFiltro == (Int32)EnumDescuentosRecargosFechasHoras.Todos ? item.DescuentoRecargoFechaHora.Id : vista.IdPromocionFiltro)
                            & item.EstaEliminado == (vista.EstadoFiltro == EnumActivoInactivo.Todos ? item.EstaEliminado : (vista.EstadoFiltro == EnumActivoInactivo.Inactivo ? true : false))
                            & (item.Existencia >= vista.ExistenciaDesdeFiltro & item.Existencia <= vista.ExistenciaHastaFiltro)
                            & (item.ExistenciaMinima >= vista.ExistenciaMinimaDesdeFiltro & item.ExistenciaMinima <= vista.ExistenciaMinimaHastaFiltro)
                            & (item.ExistenciaMaxima >= vista.ExistenciaMaximaDesdeFiltro & item.ExistenciaMaxima <= vista.ExistenciaMaximaHastaFiltro)
                            & item.TipoComision.Id == (vista.IdTipoComisionArticuloFiltro == (Byte)EnumTiposComisionesArticulos.Todos ? item.TipoComision.Id : vista.IdTipoComisionArticuloFiltro)
                            & (item.Comision >= vista.ComisionDesdeFiltro & item.Comision <= vista.ComisionHastaFiltro)
                            & (item.ComisionMaxima >= vista.ComisionMaximaDesdeFiltro & item.ComisionMaxima <= vista.ComisionMaximaHastaFiltro)
                            & item.TipoCosto.Id == (vista.IdTipoCostoArticuloFiltro == (Byte)EnumTiposCostosArticulos.Todos ? item.TipoCosto.Id : vista.IdTipoCostoArticuloFiltro)
                            & (item.Costo >= vista.CostoDesdeFiltro & item.Costo <= vista.CostoHastaFiltro)
                            & (item.Iva >= vista.IvaDesdeFiltro & item.Iva <= vista.IvaHastaFiltro)
                            & item.TipoImpuesto.Id == (vista.IdTipoImpuestoArticuloFiltro == (Byte)EnumTiposImpuestosArticulos.Todos ? item.TipoImpuesto.Id : vista.IdTipoImpuestoArticuloFiltro)
                            & (item.Impuesto >= vista.ImpuestoDesdeFiltro & item.Impuesto <= vista.ImpuestoHastaFiltro)
                            & item.Tipo.Id == (vista.IdTipoArticuloFiltro == (Byte)EnumTiposArticulos.Todos ? item.Tipo.Id : vista.IdTipoArticuloFiltro)
                            & item.TieneObservaciones == (vista.ObservacionesFiltro == EnumSiNo.Todos ? item.TieneObservaciones : (vista.ObservacionesFiltro == EnumSiNo.Si ? true : false))
                            & item.TieneImagen == (vista.ImagenFiltro == EnumSiNo.Todos ? item.TieneImagen : (vista.ImagenFiltro == EnumSiNo.Si ? true : false))
                            & (item.PrecioVentaGeneral >= vista.PrecioVentaGeneralDesdeFiltro & item.PrecioVentaGeneral <= vista.PrecioVentaGeneralHastaFiltro)
                            select item).ToList();

            var consultaCamposPersonalizados = new List<Articulo>();
            if (!String.IsNullOrWhiteSpace(vista.CampoPersonalizadoFiltro))
            {
                foreach (var articulo in consulta)
                    if (articulo.CamposPersonalizados.Count == 0)
                        consultaCamposPersonalizados.Add(articulo);
                    else
                        if (articulo.CamposPersonalizados.Where(x => x.Valor.Trim().ToLower().Contains(vista.CampoPersonalizadoFiltro)).Count() != 0)
                            consultaCamposPersonalizados.Add(articulo);
            }
            else
                consultaCamposPersonalizados.AddRange(consulta);

            var consultaSubRubros = new List<Articulo>();
            foreach (var articulo in consultaCamposPersonalizados)
                if (vista.IdSubRubrosArticulosFiltro.Contains(articulo.SubRubro.Id))
                    consultaSubRubros.Add(articulo);

            vista.ListadoArticulos = consultaSubRubros;
        }

        #endregion
    }
}
